
/**
 * Copyright 2009 cestum.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.waveprotocol.wave.model.document.operation.util {
import org.waveprotocol.wave.model.document.operation.AnnotationBoundaryMap;
import org.waveprotocol.wave.model.document.operation.Attributes;
import org.waveprotocol.wave.model.document.operation.AttributesUpdate;
import org.waveprotocol.wave.model.document.operation.BufferedDocInitialization;
import org.waveprotocol.wave.model.document.operation.BufferedDocOp;
import org.waveprotocol.wave.model.document.operation.DocInitialization;
import org.waveprotocol.wave.model.document.operation.DocumentOperation;
import org.waveprotocol.wave.model.document.operation.DocumentOperationCursor;
import org.waveprotocol.wave.model.document.operation.EvaluatingDocOpCursor;
import org.waveprotocol.wave.model.document.operation.impl.DocOpBuffer;
import org.waveprotocol.wave.model.document.operation.impl.DocumentOperationUtil;

/**
 * Decomposes an operation into units of size one
 *
 * Useful utility for writing other debugging utilities
 */
public class ExplodedDocOp implements DocumentOperation {

  private var source:DocumentOperation;

  /**
   * Operation to explode
   *
   * @param source
   */
  public function ExplodedDocOp(source:DocumentOperation) {
    this.source = source;
  }

  
  public function apply(target:DocumentOperationCursor):void {
    source.apply(new ExplodedDocOpCursor(target));
  }

  public function explodeWith(cursor:EvaluatingDocOpCursor):Object {
    apply(cursor);
    return cursor.finish();
  }

  
  
  //For overloaded add methods
  public static function explode(o:Object) {  
	  if (typeof (o) == "DocOp") {  
		  explode_docOp(DocumentOperation(o));  
	  } else if (typeof (o) == "DocInitialization") {  
		  explode_docInit(DocInitialization(o));  
	  } 
  }  
  public static function explode_docOp(op:DocumentOperation):BufferedDocOp {
    return BufferedDocOp(new ExplodedDocOp(op).explodeWith(new DocOpBuffer()));
  }

  public static function explode_docInit(op:DocInitialization):BufferedDocInitialization {
    return DocumentOperationUtil.asInitialization(explode(DocumentOperation(op))) as BufferedDocInitialization;
  }
}
}